// Thor - High Performance C++ containers and algorithm library.
//
// Copyright (c) 2010 Su Shi. All rights reserved.
//
// Author: Su Shi <carmack.shi [at] gmail.com>

// STL
#include <vector>
#include <queue>

// GTest
#include <gtest/gtest.h>

// Thor
#include <thor_priority_queue.h>

typedef thor::PriotiryQueue<int> IPQ;

const int LIMIT = 100;

TEST(IPQTest, Empty) {
  IPQ ipq;
  EXPECT_TRUE(ipq.Empty());

  ipq.Push(1);
  EXPECT_FALSE(ipq.Empty());
}

TEST(IPQTest, Size) {

  IPQ ipq;

  EXPECT_EQ(0, ipq.Size());

  ipq.Push(128);
  ipq.Push(96);
  ipq.Push(64);
  ipq.Push(32);
  ipq.Push(0);

  EXPECT_EQ(5, ipq.Size());
}

TEST(IPQTest, Top) {

  IPQ ipq;

  for (int i = -128; i <= 128; i += 32) {
    ipq.Push(i);
  }

  EXPECT_EQ(-128, ipq.Top());
}

TEST(IPQTest, Push) {

  IPQ ipq;

  for (int i = -128; i <= 128; i += 32) {
    ipq.Push(i);
  }

  EXPECT_EQ(9, ipq.Size());
}

TEST(IPQTest, Pop) {

  IPQ ipq;

  // Total 9 elements are pushed.
  for (int i = -128; i <= 128; i += 32) {
    ipq.Push(i);
  }

  int min = -128;
  size_t size = ipq.Size();
  EXPECT_EQ(9, size);

  for (size_t j = 0; j < size; ++j) {
    if (!ipq.Empty()) {
      EXPECT_EQ(min, ipq.Top());
      EXPECT_EQ(size - j, ipq.Size());
      ipq.Pop();
      min += 32;
    }
  }
}

TEST(IPQTest, PushPerformance) {
  IPQ ipq;
  for (int i = 0; i < LIMIT; ++i)
    ipq.Push(i);

  EXPECT_EQ(LIMIT, ipq.Size());

  EXPECT_EQ(0, ipq.Top());
}

TEST(STLPQTest, PushPerformance) {
  std::priority_queue<int> iq;

  for (int i = 0; i < LIMIT; ++i)
    iq.push(i);

  EXPECT_EQ(LIMIT, iq.size());

  EXPECT_EQ(LIMIT - 1, iq.top());
}
